/*
 * Android Runner is a multiplayer GPS game fully written by Xurxo Mendez Perez
 * 
 * Copyright (C) 2009 Xurxo Mendez Perez
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.androidrunner.model.persistence.player.accessor;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.ConstraintViolationException;

import es.sonxurxo.androidrunner.model.persistence.player.entity.Player;
import es.sonxurxo.androidrunner.model.persistence.util.accessor.GenericAccessorHibernate;
import es.sonxurxo.androidrunner.model.persistence.util.exceptions.DuplicateInstanceException;
import es.sonxurxo.androidrunner.model.persistence.util.exceptions.InstanceNotFoundException;
import es.sonxurxo.androidrunner.model.persistence.util.exceptions.LoginExistsException;

/**
 * 
 * @author "Xurxo Mendez Perez"
 *
 */
public class PlayerAccessorHibernate 
	extends GenericAccessorHibernate<Player, Long> 
	implements PlayerAccessor {
	
	@Override
	public void create(Player entity) 
	throws DuplicateInstanceException {

		try {
			super.create(entity);
		}
		catch (ConstraintViolationException e) {
			throw new LoginExistsException(entity, 
					Player.class.getName());
		}
	}

	public Player findByLogin(String login) 
	throws InstanceNotFoundException {
		Player player = (Player)getSession().createQuery(
				"SELECT p " +
				"FROM Player p " +
				"WHERE p.userData.login = :login").setParameter(
						"login", login).uniqueResult();
		if (player == null) {
			throw new InstanceNotFoundException(login, Player.class
					.getName());
		}
		return player;
	}

	@SuppressWarnings("unchecked")
	public List<Player> findOrderedByPoints(int startIndex, int count) {
		Criteria criteria = this.getSession().createCriteria(Player.class);
		criteria.setFirstResult(startIndex);
		criteria.setMaxResults(count);
		criteria.addOrder(Order.desc("totalPoints"));
		criteria.add(Restrictions.ne("userData.login", "admin"));
		return criteria.list();
	}
}
